package net.mingsoft.expertmanage.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.mingsoft.base.entity.ResultData;
import net.mingsoft.expertmanage.entity.CompanyEntity;
import net.mingsoft.expertmanage.entity.ExpertEntity;
import net.mingsoft.expertmanage.entity.ProjectEntity;
import net.mingsoft.expertmanage.service.ICompanyService;
import net.mingsoft.expertmanage.service.IExpertService;
import net.mingsoft.expertmanage.service.IProjectService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

/**
 * 专家管理控制器
 */
@Api(value = "专家管理接口")
@Controller
@RequestMapping("/${ms.manager.path}/expertmanage/expert")
public class ExpertController {

    private static final Logger LOG = LoggerFactory.getLogger(ExpertController.class);

    @Autowired
    private IExpertService expertService;
    
    @Autowired(required = false)
    private IProjectService projectService;
    
    @Autowired(required = false)
    private ICompanyService companyService;

    /**
     * 查询专家列表
     */
    @ApiOperation(value = "查询专家列表")
    @GetMapping("/list")
    @ResponseBody
    public ResultData list(@RequestParam(value = "pageNum", required = false, defaultValue = "1") int pageNum,
                           @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize,
                           @RequestParam(value = "keyword", required = false) String keyword) {
        // 打印参数信息
        Page<ExpertEntity> page = new Page<>(pageNum, pageSize);
        QueryWrapper<ExpertEntity> queryWrapper = new QueryWrapper<>();
        
        if (keyword != null && !keyword.isEmpty()) {
            queryWrapper.like("name", keyword).or()
                      .like("expert_code", keyword).or()
                      .like("research_keywords", keyword);
        }
        
        return ResultData.build().success(expertService.page(page, queryWrapper));
    }

    /**
     * 专家添加表单页面
     */
    @ApiOperation(value = "专家添加表单页面")
    @GetMapping("/form")
    public String form(ModelMap model) {
        // 获取当前最大序号，为新专家生成建议的序号
        Integer maxSerialNo = expertService.getMaxSerialNo();
        model.addAttribute("nextSerialNo", maxSerialNo != null ? maxSerialNo + 1 : 1);
        return "/expertmanage/expert/form";
    }

    /**
     * 保存专家
     */
    @ApiOperation(value = "保存专家")
    @PostMapping("/save")
    @ResponseBody
    public ResultData save(@RequestBody ExpertEntity expert) {
        // 验证必填字段
        if (expert == null || StringUtils.isEmpty(expert.getExpertCode()) || StringUtils.isEmpty(expert.getName())) {
            return ResultData.build().error("专家编号和姓名不能为空");
        }
        
        // 检查专家编号是否已存在
        ExpertEntity existingExpert = expertService.getByExpertCode(expert.getExpertCode());
        if (existingExpert != null) {
            return ResultData.build().error("专家编号已存在，请更换编号");
        }
        
        try {
            // 保存专家信息
            expertService.save(expert);
            return ResultData.build().success("专家信息保存成功");
        } catch (Exception e) {
            return ResultData.build().error("保存失败：" + e.getMessage());
        }
    }

    /**
     * 更新专家
     */
    @ApiOperation(value = "更新专家")
    @PostMapping("/update")
    @ResponseBody
    public ResultData update(ExpertEntity expert) {
        expertService.updateById(expert);
        return ResultData.build().success();
    }

    /**
     * 删除专家及关联信息
     */
    @ApiOperation(value = "删除专家及关联信息")
    @PostMapping("/delete/{expertCode}")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public ResultData delete(@PathVariable("expertCode") String expertCode) {
        try {
            if (StringUtils.isEmpty(expertCode)) {
                return ResultData.build().error("专家编号不能为空");
            }
            
            // 1. 获取专家信息确认存在
            ExpertEntity expert = expertService.getByExpertCode(expertCode);
            if (expert == null) {
                return ResultData.build().error("未找到对应的专家信息");
            }
            
            // 2. 清理项目关联
            if (projectService != null) {
                // 2.1 获取关联的项目
                List<ProjectEntity> leaderProjects = projectService.getByLeaderCode(expertCode);
                
                // 2.2 清理作为项目负责人的关联
                if (leaderProjects != null && !leaderProjects.isEmpty()) {
                    for (ProjectEntity project : leaderProjects) {
                        // 将负责人设置为空
                        project.setLeaderCode(null);
                        projectService.updateById(project);
                        LOG.info("已清理项目{}的负责人关联", project.getProjectCode());
                    }
                }
                
                // 2.3 清理作为项目参与者的关联
                List<ProjectEntity> participantProjects = projectService.getByExpertCode(expertCode);
                if (participantProjects != null && !participantProjects.isEmpty()) {
                    for (ProjectEntity project : participantProjects) {
                        if (project.getParticipantExperts() != null) {
                            // 从参与者字段中移除当前专家编号
                            String participants = project.getParticipantExperts();
                            participants = participants.replace(expertCode + ",", "")
                                    .replace("," + expertCode, "")
                                    .replace(expertCode, "");
                            project.setParticipantExperts(participants);
                            projectService.updateById(project);
                            LOG.info("已清理项目{}的参与者关联", project.getProjectCode());
                        }
                    }
                }
            }
            
            // 3. 清理企业关联
            if (companyService != null) {
                List<CompanyEntity> companies = companyService.getByExpertCode(expertCode);
                
                if (companies != null && !companies.isEmpty()) {
                    for (CompanyEntity company : companies) {
                        // 从matched_expert_codes字段中移除当前专家编号
                        if (company.getMatchedExpertCodes() != null) {
                            String matchedExperts = company.getMatchedExpertCodes();
                            matchedExperts = matchedExperts.replace(expertCode + ",", "")
                                    .replace("," + expertCode, "")
                                    .replace(expertCode, "");
                            company.setMatchedExpertCodes(matchedExperts);
                            companyService.updateById(company);
                            LOG.info("已清理企业{}的专家关联", company.getCompanyCode());
                        }
                    }
                }
            }
            
            // 4. 删除专家
            boolean success = expertService.removeById(expertCode);
            
            if (success) {
                LOG.info("成功删除专家: {}", expertCode);
                return ResultData.build().success("专家及关联信息已成功删除");
            } else {
                return ResultData.build().error("删除专家失败");
            }
        } catch (Exception e) {
            LOG.error("删除专家时发生错误: " + e.getMessage(), e);
            return ResultData.build().error("删除专家时发生错误: " + e.getMessage());
        }
    }

    /**
     * 批量删除专家
     */
    @ApiOperation(value = "批量删除专家")
    @PostMapping("/delete")
    @ResponseBody
    public ResultData delete(@RequestBody List<String> expertCodes) {
        try {
            if (expertCodes == null || expertCodes.isEmpty()) {
                return ResultData.build().error("专家编号列表不能为空");
            }
            
            // 对每个专家单独处理，以确保关联数据处理
            int successCount = 0;
            StringBuilder errorMsg = new StringBuilder();
            
            for (String expertCode : expertCodes) {
                try {
                    ResultData result = this.delete(expertCode);
                    if (result != null && result.toString().contains("成功")) {
                        successCount++;
                    } else {
                        errorMsg.append(expertCode).append(": ").append(result != null ? result.toString() : "未知错误").append("; ");
                    }
                } catch (Exception e) {
                    errorMsg.append(expertCode).append(": ").append(e.getMessage()).append("; ");
                }
            }
            
            if (successCount == expertCodes.size()) {
                return ResultData.build().success("成功删除所有专家");
            } else if (successCount > 0) {
                return ResultData.build().success("部分删除成功: " + successCount + "/" + expertCodes.size() + "。错误: " + errorMsg);
            } else {
                return ResultData.build().error("全部删除失败: " + errorMsg);
            }
        } catch (Exception e) {
            LOG.error("批量删除专家时发生错误: " + e.getMessage(), e);
            return ResultData.build().error("批量删除专家时发生错误: " + e.getMessage());
        }
    }

    /**
     * 获取所有专家列表（不分页）
     */
    @ApiOperation(value = "获取所有专家")
    @GetMapping("/all")
    @ResponseBody
    public ResultData getAll() {
        return ResultData.build().success(expertService.list());
    }
    
    /**
     * 根据专家编号获取专家详情
     */
    @ApiOperation(value = "根据专家编号获取专家详情")
    @GetMapping("/getByCode")
    @ResponseBody
    public ResultData getByCode(@RequestParam("expertCode") String expertCode) {
        if (StringUtils.isEmpty(expertCode)) {
            return ResultData.build().error("专家编号不能为空");
        }
        
        ExpertEntity expert = expertService.getByExpertCode(expertCode);
        if (expert == null) {
            return ResultData.build().error("未找到对应的专家信息");
        }
        
        return ResultData.build().success(expert);
    }
    
    /**
     * 导入专家
     */
    @ApiOperation(value = "导入专家")
    @PostMapping("/import")
    @ResponseBody
    public ResultData importExperts(HttpServletRequest request, HttpServletResponse response) {
        try {
            MultipartFile file = (MultipartFile) request.getAttribute("file");
            if (file == null) {
                return ResultData.build().error("请选择要导入的Excel文件");
            }
            String result = expertService.importExcel(file);
            return ResultData.build().success(result);
        } catch (Exception e) {
            return ResultData.build().error(e.getMessage());
        }
    }
    
    /**
     * 下载导入模板
     */
    @ApiOperation(value = "下载导入模板")
    @GetMapping("/template")
    public void downloadTemplate(HttpServletResponse response) {
        try {
            // 重定向到RelationController的模板下载功能
            response.sendRedirect("../relation/importTemplate/expert");
        } catch (IOException e) {
            LOG.error("模板下载失败", e);
        }
    }

    /**
     * 专家管理页面
     */
    @ApiOperation(value = "专家管理页面")
    @GetMapping("/index")
    public String index() {
        return "/expertmanage/expert/index";
    }
    
    /**
     * 保存专家关联信息（专家、项目、企业）
     */
    @ApiOperation(value = "保存专家关联信息")
    @PostMapping("/saveRelations")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public ResultData saveRelations(@RequestBody Map<String, Object> formData) {
        try {
            // 1. 保存专家信息
            Map<String, Object> expertMap = (Map<String, Object>) formData.get("expert");
            ExpertEntity expert = new ExpertEntity();
            
            // 手动映射专家属性
            if (expertMap.containsKey("expertCode")) expert.setExpertCode((String) expertMap.get("expertCode"));
            if (expertMap.containsKey("name")) expert.setName((String) expertMap.get("name"));
            if (expertMap.containsKey("gender")) expert.setGender((String) expertMap.get("gender"));
            if (expertMap.containsKey("age") && expertMap.get("age") != null) {
                expert.setAge(Integer.parseInt(expertMap.get("age").toString()));
            }
            if (expertMap.containsKey("title")) expert.setTitle((String) expertMap.get("title"));
            if (expertMap.containsKey("highestEducation")) expert.setHighestEducation((String) expertMap.get("highestEducation"));
            if (expertMap.containsKey("firstLevelDiscipline")) expert.setFirstLevelDiscipline((String) expertMap.get("firstLevelDiscipline"));
            if (expertMap.containsKey("secondLevelDiscipline")) expert.setSecondLevelDiscipline((String) expertMap.get("secondLevelDiscipline"));
            if (expertMap.containsKey("college")) expert.setCollege((String) expertMap.get("college"));
            if (expertMap.containsKey("insideOutside")) expert.setInsideOutside((String) expertMap.get("insideOutside"));
            if (expertMap.containsKey("researchKeywords")) expert.setResearchKeywords((String) expertMap.get("researchKeywords"));
            if (expertMap.containsKey("achievementType")) expert.setAchievementType((String) expertMap.get("achievementType"));
            if (expertMap.containsKey("ipOwnership")) expert.setIpOwnership((String) expertMap.get("ipOwnership"));
            if (expertMap.containsKey("socialPositions")) expert.setSocialPositions((String) expertMap.get("socialPositions"));
            if (expertMap.containsKey("verticalProjects")) expert.setVerticalProjects((String) expertMap.get("verticalProjects"));
            if (expertMap.containsKey("horizontalProjects")) expert.setHorizontalProjects((String) expertMap.get("horizontalProjects"));
            if (expertMap.containsKey("contact")) expert.setContact((String) expertMap.get("contact"));
            if (expertMap.containsKey("remarks")) expert.setRemarks((String) expertMap.get("remarks"));
            if (expertMap.containsKey("serialNo") && expertMap.get("serialNo") != null) {
                expert.setSerialNo(Integer.parseInt(expertMap.get("serialNo").toString()));
            }
            
            // 验证必填字段
            if (StringUtils.isEmpty(expert.getExpertCode()) || StringUtils.isEmpty(expert.getName())) {
                return ResultData.build().error("专家编号和姓名不能为空");
            }
            
            // 检查专家编号是否已存在
            ExpertEntity existingExpert = expertService.getByExpertCode(expert.getExpertCode());
            if (existingExpert != null) {
                return ResultData.build().error("专家编号已存在，请更换编号");
            }
            
            // 保存专家信息
            expertService.save(expert);
            
            // 2. 保存关联的项目信息
            if (projectService != null && formData.containsKey("projects") && formData.get("projects") != null) {
                List<Map<String, Object>> projectsList = (List<Map<String, Object>>) formData.get("projects");
                for (Map<String, Object> projectMap : projectsList) {
                    if (projectMap == null || !projectMap.containsKey("projectCode") || 
                        StringUtils.isEmpty((String) projectMap.get("projectCode"))) {
                        continue; // 跳过没有项目编号的数据
                    }
                    
                    ProjectEntity project = new ProjectEntity();
                    // 手动映射项目属性
                    if (projectMap.containsKey("projectCode")) project.setProjectCode((String) projectMap.get("projectCode"));
                    if (projectMap.containsKey("projectName")) project.setProjectName((String) projectMap.get("projectName"));
                    if (projectMap.containsKey("department")) project.setDepartment((String) projectMap.get("department"));
                    if (projectMap.containsKey("leaderCode")) {
                        project.setLeaderCode((String) projectMap.get("leaderCode"));
                    } else {
                        project.setLeaderCode(expert.getExpertCode()); // 默认关联当前专家
                    }
                    if (projectMap.containsKey("participantExperts")) project.setParticipantExperts((String) projectMap.get("participantExperts"));
                    if (projectMap.containsKey("projectType")) project.setProjectType((String) projectMap.get("projectType"));
                    if (projectMap.containsKey("techMaturity")) project.setTechMaturity((String) projectMap.get("techMaturity"));
                    if (projectMap.containsKey("coreTechKeywords")) project.setCoreTechKeywords((String) projectMap.get("coreTechKeywords"));
                    if (projectMap.containsKey("applicationIndustry")) project.setApplicationIndustry((String) projectMap.get("applicationIndustry"));
                    if (projectMap.containsKey("marketStage")) project.setMarketStage((String) projectMap.get("marketStage"));
                    if (projectMap.containsKey("budget")) project.setBudget((String) projectMap.get("budget"));
                    if (projectMap.containsKey("cooperationTendency")) project.setCooperationTendency((String) projectMap.get("cooperationTendency"));
                    if (projectMap.containsKey("remarks")) project.setRemarks((String) projectMap.get("remarks"));
                    
                    // 保存项目信息
                    projectService.save(project);
                }
            }
            
            // 3. 保存关联的企业信息
            if (companyService != null && formData.containsKey("companies") && formData.get("companies") != null) {
                List<Map<String, Object>> companiesList = (List<Map<String, Object>>) formData.get("companies");
                for (Map<String, Object> companyMap : companiesList) {
                    if (companyMap == null || !companyMap.containsKey("companyCode") || 
                        StringUtils.isEmpty((String) companyMap.get("companyCode"))) {
                        continue; // 跳过没有企业编号的数据
                    }
                    
                    CompanyEntity company = new CompanyEntity();
                    // 手动映射企业属性
                    if (companyMap.containsKey("companyCode")) company.setCompanyCode((String) companyMap.get("companyCode"));
                    if (companyMap.containsKey("companyName")) company.setCompanyName((String) companyMap.get("companyName"));
                    if (companyMap.containsKey("companyType")) company.setCompanyType((String) companyMap.get("companyType"));
                    if (companyMap.containsKey("industryPrimary")) company.setIndustryPrimary((String) companyMap.get("industryPrimary"));
                    if (companyMap.containsKey("industrySecondary")) company.setIndustrySecondary((String) companyMap.get("industrySecondary"));
                    if (companyMap.containsKey("registrationAddress")) company.setRegistrationAddress((String) companyMap.get("registrationAddress"));
                    if (companyMap.containsKey("contactPerson")) company.setContactPerson((String) companyMap.get("contactPerson"));
                    if (companyMap.containsKey("contactInfo")) company.setContactInfo((String) companyMap.get("contactInfo"));
                    if (companyMap.containsKey("businessKeywords")) company.setBusinessKeywords((String) companyMap.get("businessKeywords"));
                    if (companyMap.containsKey("requiredTechField")) company.setRequiredTechField((String) companyMap.get("requiredTechField"));
                    if (companyMap.containsKey("cooperationStatus")) company.setCooperationStatus((String) companyMap.get("cooperationStatus"));
                    if (companyMap.containsKey("remarks")) company.setRemarks((String) companyMap.get("remarks"));
                    
                    // 将当前专家编号添加到企业的对接专家列表中
                    company.setMatchedExpertCodes(expert.getExpertCode());
                    
                    // 保存企业信息
                    companyService.save(company);
                }
            }
            
            return ResultData.build().success("专家关联信息保存成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultData.build().error("保存失败：" + e.getMessage());
        }
    }

    /**
     * 根据专家编号获取专家详细信息
     */
    @ApiOperation(value = "根据专家编号获取专家详细信息")
    @GetMapping("/get")
    @ResponseBody
    public ResultData get(@RequestParam("expertCode") String expertCode) {
        if (StringUtils.isEmpty(expertCode)) {
            return ResultData.build().error("专家编号不能为空");
        }
        
        ExpertEntity expert = expertService.getByExpertCode(expertCode);
        if (expert == null) {
            return ResultData.build().error("未找到对应的专家信息");
        }
        
        return ResultData.build().success(expert);
    }
} 